#pragma once
#include<string>
#include <unistd.h>
#include <sys/wait.h>
#include <cstdlib>
#include <fcntl.h>
#include"../comm/FileTools.hpp"
#include"../comm/log.hpp"
#include"Compiler.hpp"
#include"Runner.hpp"
//准备工作 创建.cpp文件，填入代码 创建.stdin文件，填入stdin 创建子进程，文件重定向
//编译
//运行
//结果收集

using namespace Ns_FileTools;
using namespace Ns_Log;
class Controler
{
    public:
    bool compile_run(const std::string& code,const std::string& _stdin,int& status,std::string& result_message)
    {
        std::string filename;
        //准备工作
        if(!initialize(code,_stdin,filename))
        {
            log(ERROR,"initialize error");
            return false;
        }
        //编译运行
        start(filename);
        //结果收集
        results(filename,status,result_message);
        //资源清理
        FileTools::FilesClean(filename);
        return true;
    }
    private:
    const string prefix_dir="./WorkFiles/";
    bool initialize(const std::string& code,const std::string& _stdin,std::string& filename)
    {
        //准备工作
        filename=prefix_dir+FileTools::GenerateUniqueFileName();
        
        if(!FileTools::CreateFileAndWrite(filename+".cpp",code)||
        !FileTools::CreateFileAndWrite(filename+".stdin",_stdin)||
        !FileTools::CreateFileAndWrite(filename+".stdout","")||
        !FileTools::CreateFileAndWrite(filename+".stderr",""))
        {
            log(ERROR,"准备工作，创建启动文件失败");
            return false;
        }

        return true;
    }
    void start(const std::string& filename)
    {
        if(Compiler::compile(filename))
        {
            Runner::run(filename);
        }
    }
    void results(const std::string& filename,int& status,std::string& result_message)
    {
        //结果收集，读取.stdout和.stderr

        string _stderr;
        if(!FileTools::ReadFileToString(filename+".stderr",_stderr))
        {
            log(ERROR,"编译运行结果收集时，读取文件失败");
            return;
        }
        if(!_stderr.empty())
        {
            //错误信息
            status=1;
            result_message=_stderr;
            return;
        }

        string _stdout;
        if(!FileTools::ReadFileToString(filename+".stdout",_stdout))
        {
            log(ERROR,"编译运行结果收集时，读取文件失败");
            return;
        }
        status=0;
        result_message=_stdout;
    }
};